package com.fu.utils;

import java.security.InvalidParameterException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.lang3.time.DateUtils;

/**
* @Class : DateTimeUtils
* @description : 时间操作工具类
* @author : Little Ant
* @creation Date : 2017/11/1
* @ModificationHistory   who      when        what
* -------  -----------  ------------------------------
*/
public class DateTimeUtils {
	public static final int YEAR = 1;
	public static final int MONTH = 2;
	public static final int DAY = 5;
	public static final int HOUR = 10;
	public static final int HOUR_OF_DAY = 11;
	public static final int MINUTE = 12;
	public static final int SECOND = 13;
	public static final String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
	public static final String DATE_TIMESTAMP_FORMAT = "yyyy-MM-dd HH:mm:ss.SSS";
	public static final String DATE_FORMAT = "yyyy-MM-dd";
	public static final String TIME_FORMAT = "HH:mm:ss";

	public static Date addYears(Date date, int amount) {
		return DateUtils.addYears(date, amount);
	}

	public static Date addMonths(Date date, int amount) {
		return DateUtils.addMonths(date, amount);
	}

	public static Date addWeeks(Date date, int amount) {
		return DateUtils.addWeeks(date, amount);
	}

	public static Date addDays(Date date, int amount) {
		return DateUtils.addDays(date, amount);
	}

	public static Date addHours(Date date, int amount) {
		return DateUtils.addHours(date, amount);
	}

	public static Date addMinutes(Date date, int amount) {
		return DateUtils.addMinutes(date, amount);
	}

	public static Date addSeconds(Date date, int amount) {
		return DateUtils.addSeconds(date, amount);
	}

	public static Date addMilliseconds(Date date, int amount) {
		return DateUtils.addMilliseconds(date, amount);
	}

	public static Date truncate(Date date, int field) {
		return DateUtils.truncate(date, field);
	}

	public static int intervalYears(Date beginDate, Date endDate) {
		if (beginDate.after(endDate)) {
			Date tmp = endDate;
			endDate = beginDate;
			beginDate = tmp;
		}

		int endDateYear = getYear(endDate);
		int beginDateYear = getYear(beginDate);

		int interval = endDateYear - beginDateYear;

		return interval;
	}

	public static int intervalMonths(Date beginDate, Date endDate) {
		if (beginDate.after(endDate)) {
			Date tmp = endDate;
			endDate = beginDate;
			beginDate = tmp;
		}

		int endDateYear = getYear(endDate);
		int beginDateYear = getYear(beginDate);

		int intervalYear = endDateYear - beginDateYear;

		int endDateMonth = getMonth(endDate);
		int beginDateMonth = getMonth(beginDate);

		int intervalMonth = 0;
		if (endDateMonth < beginDateMonth) {
			--intervalYear;
			intervalMonth = endDateMonth + 12 - beginDateMonth;
		} else {
			intervalMonth = endDateMonth - beginDateMonth;
		}

		return (intervalYear * 12 + intervalMonth);
	}

	public static int intervalDays(Date beginDate, Date endDate) {
		if (beginDate.after(endDate)) {
			Date tmp = endDate;
			endDate = beginDate;
			beginDate = tmp;
		}

		beginDate = truncate(beginDate, 5);
		endDate = truncate(endDate, 5);

		long interval = endDate.getTime() - beginDate.getTime();

		return (int) (interval / 86400000L);
	}

	public static int intervalHours(Date beginDate, Date endDate) {
		if (beginDate.after(endDate)) {
			Date tmp = endDate;
			endDate = beginDate;
			beginDate = tmp;
		}

		beginDate = truncate(beginDate, 10);
		endDate = truncate(endDate, 10);

		long interval = endDate.getTime() - beginDate.getTime();

		return (int) (interval / 3600000L);
	}

	public static int intervalMinutes(Date beginDate, Date endDate) {
		if (beginDate.after(endDate)) {
			Date tmp = endDate;
			endDate = beginDate;
			beginDate = tmp;
		}
		return getIntervalMinutes(beginDate, endDate);
	}

	public static int getIntervalMinutes(Date beginDate, Date endDate) {
		beginDate = truncate(beginDate, 12);
		endDate = truncate(endDate, 12);

		long interval = endDate.getTime() - beginDate.getTime();

		return (int) (interval / 60000L);
	}

	public static int getIntervalMinutes(String beginStamp, String endStamp) {
		long interval = Long.valueOf(endStamp) - Long.valueOf(beginStamp);
		return (int) (interval / 60000L);
	}

	public static long intervalSeconds(Date beginDate, Date endDate) {
		if (beginDate.after(endDate)) {
			Date tmp = endDate;
			endDate = beginDate;
			beginDate = tmp;
		}

		long interval = endDate.getTime() - beginDate.getTime();

		return (int) (interval / 1000L);
	}

	public static int getYear(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);

		return calendar.get(1);
	}

	public static int getMonth(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);

		return (calendar.get(2) + 1);
	}

	public static int getDay(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);

		return calendar.get(5);
	}

	public static int getHour(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);

		return calendar.get(10);
	}

	public static int getHourOfDay(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		int day = calendar.get(11);
		return day;
	}

	public static Date setHourOfDay(Date date, int amount) {
		return DateUtils.setHours(date, amount);
	}

	public static int getMinute(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		return calendar.get(12);
	}

	public static Date setMinute(Date date, int amount) {
		return DateUtils.setMinutes(date, amount);
	}

	public static int getSecond(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);

		return calendar.get(13);
	}

	public static Date setSecond(Date date, int amount) {
		return DateUtils.setSeconds(date, amount);
	}

	public static String format(Date date, String pattern) {
		if (StringUtils.isEmpty(pattern)){
			pattern = "yyyy-MM-dd HH:mm:ss";
		}

		return DateFormatUtils.format(date, pattern);
	}

	public static String format(String dateString, String pattern, String desPattern) throws ParseException {
		if (StringUtils.isEmpty(pattern)){
			pattern = "yyyy-MM-dd HH:mm:ss";
		}

		Date date = DateUtils.parseDate(dateString, new String[] { pattern });

		return format(date, desPattern);
	}

	public static Date convert(String date, String pattern) throws ParseException {
		if (StringUtils.isEmpty(pattern)){
			pattern = "yyyy-MM-dd HH:mm:ss";
		}

		SimpleDateFormat sdf = new SimpleDateFormat(pattern);

		return sdf.parse(date);
	}

	public static Date parseDate(String dateString) {
		try {
			return DateUtils.parseDate(dateString,
					new String[] { "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd", "HH:mm:ss", "yyyy-MM-dd HH:mm:ss.SSS" });
		} catch (ParseException e) {
			throw new InvalidParameterException(dateString + "不是一个正确格式的日期。");
		}
	}

	public static boolean isTimeBetween(Date startTime, Date endTime, Date dateTime) {
		return ((((dateTime.equals(startTime)) || (dateTime.after(startTime)))) && (dateTime.before(endTime)));
	}
}